{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d8fdb577",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import math\n",
    "from tqdm import tqdm\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "format_data = {\n",
    "        \"device_id\":[],\n",
    "        \"cpu_id\":[],\n",
    "        \"record_id\":[],\n",
    "        \"timestamp\":[],\n",
    "        \"process_id\":[],\n",
    "        \"trace_action\":[],\n",
    "        \"operation_type\":[], #N操作的时候，没有扇区num，没有IOsize，只有进程name\n",
    "        \"sector_num\":[],\n",
    "        \"IO_size\":[],\n",
    "        \"process_name\":[]\n",
    "    }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "761f0925",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_data():\n",
    "    data = pd.read_csv('../data_set/map-1.csv',delimiter ='\\t',header=None)\n",
    "    #data = pd.read_csv('../data_set/ssdtrace-sample',delimiter ='\\t',header=None)\n",
    "    return data   \n",
    "data = get_data()\n",
    "print(data.shape)\n",
    "print(data.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e97156b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_format_data(data):\n",
    "    global error_data\n",
    "    all_data = []\n",
    "    error_data = []\n",
    "    for line in tqdm(data[0]):\n",
    "        lst = line.split(' ')\n",
    "        true_data = []\n",
    "        for i in lst:\n",
    "            if len(i)>0 :\n",
    "                #print(i)\n",
    "                true_data.append(i)\n",
    "        if len(true_data)>6:\n",
    "            all_data.append(true_data)\n",
    "        else:\n",
    "            error_data.append(true_data)\n",
    "    return all_data\n",
    "lst_data = get_format_data(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "835c4838",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(lst_data[:5])\n",
    "print(error_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac6146f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "tp = set()\n",
    "\n",
    "for lst in lst_data:\n",
    "    if len(lst)<=9:\n",
    "        tp.add(lst[6])\n",
    "    if len(lst)<=9 and lst[6]==\"WS\": #可以看出WS类型的没有sector number  IO size为0  属于0号进程\n",
    "        print(lst)\n",
    "print(tp)  # 说明这四种情况下 没有后续的内容"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5bf404ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_N = []\n",
    "sample_FWS = []\n",
    "sample_WS = []\n",
    "sample_WFS = []\n",
    "for lst in lst_data:\n",
    "    if lst[6]=='N':\n",
    "        sample_N.append(lst)\n",
    "    elif lst[6]==\"FWS\":\n",
    "        sample_FWS.append(lst)\n",
    "    elif lst[6]==\"WS\":\n",
    "        sample_WS.append(lst)\n",
    "    elif lst[6]==\"WFS\":\n",
    "        sample_WFS.append(lst)\n",
    "\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f08e1c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(len(sample_N),sample_N[0]) # N 和 FWS都是可以拼接的\n",
    "print(len(sample_WS),sample_WS[0]) \n",
    "print(len(sample_FWS),sample_FWS[0]) \n",
    "print(len(sample_WFS),sample_WFS[0]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e66f0da",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in sample_FWS:  \n",
    "    if len(i)<=9:\n",
    "        print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "faa2064f",
   "metadata": {},
   "outputs": [],
   "source": [
    "cnt = 0\n",
    "for i in sample_WFS:\n",
    "    cnt+=1\n",
    "    if cnt>10:\n",
    "        break\n",
    "    print(i)   #WFS的必须区分有没有+号"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c1e592b",
   "metadata": {},
   "source": [
    "综上分析出的特例IO:\n",
    "1. WFS类型操作区分0号进程且是sector操作(lst[8]是+号) 这个len<9 需要特殊处理\n",
    "2. N 和 FWS也都是len<9  N的取[java]作为processname   FWS的都有特定的名称且len比N还小 直接取最后一个作为process即可\n",
    "3. WS的区分0号进程  需要特殊处理   其他的同WFS可以不用特殊处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7de2c61f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "\n",
    "origin_formate_data = copy.copy(format_data)\n",
    "format_data = origin_formate_data\n",
    "print(len(origin_formate_data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "508ce2b3",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "for lst in lst_data:\n",
    "\n",
    "    if lst[6]!='N' and lst[6]!=\"FWS\" and lst[6]!=\"WFS\" and  lst[6]!=\"WS\":#不是这个分支\n",
    "        format_data[\"device_id\"].append(lst[0])\n",
    "        format_data[\"cpu_id\"].append(lst[1])\n",
    "        format_data[\"record_id\"].append(lst[2])\n",
    "        format_data[\"timestamp\"].append(lst[3])\n",
    "        format_data[\"process_id\"].append(lst[4])\n",
    "        format_data[\"trace_action\"].append(lst[5])\n",
    "        format_data[\"operation_type\"].append(lst[6])\n",
    "        format_data[\"sector_num\"].append(lst[7])\n",
    "        format_data[\"IO_size\"].append(lst[9])\n",
    "        format_data[\"process_name\"].append(lst[-1])\n",
    "\n",
    "    else:\n",
    "        if lst[6]=='N':#不是这个分支\n",
    "            format_data[\"device_id\"].append(lst[0])\n",
    "            format_data[\"cpu_id\"].append(lst[1])\n",
    "            format_data[\"record_id\"].append(lst[2])\n",
    "            format_data[\"timestamp\"].append(lst[3])\n",
    "            format_data[\"process_id\"].append(lst[4])\n",
    "            format_data[\"trace_action\"].append(lst[5])\n",
    "            format_data[\"operation_type\"].append(lst[6]) #N\n",
    "            format_data[\"sector_num\"].append(0)\n",
    "            format_data[\"IO_size\"].append(0)\n",
    "            format_data[\"process_name\"].append(lst[-1])\n",
    "        elif lst[6]==\"WFS\": #不是这个分支\n",
    "            \n",
    "            if lst[8]!=\"+\":\n",
    "            #['259,2', '19', '3996', '7.120903570', '0', 'C', 'WFS', '499613064', '[0]']\n",
    "                format_data[\"device_id\"].append(lst[0])\n",
    "                format_data[\"cpu_id\"].append(lst[1])\n",
    "                format_data[\"record_id\"].append(lst[2])\n",
    "                format_data[\"timestamp\"].append(lst[3])\n",
    "                format_data[\"process_id\"].append(lst[4])\n",
    "                format_data[\"trace_action\"].append(lst[5])\n",
    "                format_data[\"operation_type\"].append(lst[6]) \n",
    "                format_data[\"sector_num\"].append(lst[7])\n",
    "                format_data[\"IO_size\"].append(0)\n",
    "                format_data[\"process_name\"].append(lst[-1])\n",
    "            else:\n",
    "                #['259,2', '1', '13708', '27.635742637', '1062', 'D', 'WFS', '499617592', '+', '8', '[kworker/1:1H]']\n",
    "                #['259,2', '1', '13710', '27.639087693', '4053', 'C', 'WFS', '499617592', '+', '8', '[0]']\n",
    "                format_data[\"device_id\"].append(lst[0])\n",
    "                format_data[\"cpu_id\"].append(lst[1])\n",
    "                format_data[\"record_id\"].append(lst[2])\n",
    "                format_data[\"timestamp\"].append(lst[3])\n",
    "                format_data[\"process_id\"].append(lst[4])\n",
    "                format_data[\"trace_action\"].append(lst[5])\n",
    "                format_data[\"operation_type\"].append(lst[6])\n",
    "                format_data[\"sector_num\"].append(lst[7])\n",
    "                format_data[\"IO_size\"].append(lst[9])\n",
    "                format_data[\"process_name\"].append(lst[-1])\n",
    "        elif lst[6]==\"WS\":#不是这个分支\n",
    "            if lst[-1]==\"[0]\":\n",
    "            #['259,2', '1', '64942', '132.546605808', '4086', 'C', 'WS', '0', '[0]']\n",
    "                format_data[\"device_id\"].append(lst[0])\n",
    "                format_data[\"cpu_id\"].append(lst[1])\n",
    "                format_data[\"record_id\"].append(lst[2])\n",
    "                format_data[\"timestamp\"].append(lst[3])\n",
    "                format_data[\"process_id\"].append(lst[4])\n",
    "                format_data[\"trace_action\"].append(lst[5])\n",
    "                format_data[\"operation_type\"].append(lst[6]) \n",
    "                format_data[\"sector_num\"].append(0) #用不到\n",
    "                format_data[\"IO_size\"].append(0)\n",
    "                format_data[\"process_name\"].append(lst[-1])\n",
    "            else: \n",
    "                format_data[\"device_id\"].append(lst[0])\n",
    "                format_data[\"cpu_id\"].append(lst[1])\n",
    "                format_data[\"record_id\"].append(lst[2])\n",
    "                format_data[\"timestamp\"].append(lst[3])\n",
    "                format_data[\"process_id\"].append(lst[4])\n",
    "                format_data[\"trace_action\"].append(lst[5])\n",
    "                format_data[\"operation_type\"].append(lst[6])\n",
    "                format_data[\"sector_num\"].append(lst[7])\n",
    "                format_data[\"IO_size\"].append(lst[9])\n",
    "                format_data[\"process_name\"].append(lst[-1])\n",
    "            #['259,2', '2', '2638', '1.641824430', '4020', 'Q', 'WS', '7487488', '+', '2048', '[java]']\n",
    "        elif lst[6]==\"FWS\":\n",
    "            #['259,2', '1', '64940', '132.545984928', '4092', 'Q', 'FWS', '[rocksdb:bg0]']\n",
    "            format_data[\"device_id\"].append(lst[0])\n",
    "            format_data[\"cpu_id\"].append(lst[1])\n",
    "            format_data[\"record_id\"].append(lst[2])\n",
    "            format_data[\"timestamp\"].append(lst[3])\n",
    "            format_data[\"process_id\"].append(lst[4])\n",
    "            format_data[\"trace_action\"].append(lst[5])\n",
    "            format_data[\"operation_type\"].append(lst[6]) \n",
    "            format_data[\"sector_num\"].append(0) #用不到\n",
    "            format_data[\"IO_size\"].append(0)#用不到\n",
    "            format_data[\"process_name\"].append(lst[-1])\n",
    "            \n",
    "\n",
    "\n",
    "print(len(format_data[\"device_id\"]))\n",
    "print(len(format_data[\"cpu_id\"]))\n",
    "print(len(format_data[\"record_id\"]))\n",
    "print(len(format_data[\"timestamp\"]))\n",
    "print(len(format_data[\"process_id\"]))\n",
    "print(len(format_data[\"trace_action\"]))\n",
    "print(len(format_data[\"operation_type\"]))\n",
    "print(len(format_data[\"sector_num\"]))\n",
    "print(len(format_data[\"IO_size\"]))\n",
    "print(len(format_data[\"process_name\"]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a55fdb7c",
   "metadata": {},
   "outputs": [],
   "source": [
    "                \n",
    "column_name = [ \"device_id\",\n",
    " \"cpu_id\",\n",
    " \"record_id\",\n",
    " \"timestamp\",\n",
    " \"process_id\",\n",
    " \"trace_action\",\n",
    " \"operation_type\",\n",
    " \"sector_num\",\n",
    " \"IO_size\",\n",
    " \"process_name\"]\n",
    "data = pd.DataFrame(format_data,columns=column_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5054f349",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(data.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be2cb67d",
   "metadata": {},
   "outputs": [],
   "source": [
    "load0_request_num = data.shape[0]\n",
    "load0_request_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0e688aa5",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b623777",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "def cnt_r_1s(beginS,deltaSecond=1):#以1s为单位  beginS 应该是float   计算[beginS,beginS+deltaSecond] 时间段内的读请求数目\n",
    "#     beginS = eval(beginS)\n",
    "    read_data = data[data[\"operation_type\"]==\"R\"]  \n",
    "    syn_read_data =  data[data[\"operation_type\"]==\"RS\"]\n",
    "    ahead_read_data  = data[data[\"operation_type\"]==\"A\"]#预读也算\n",
    "    cnt = 0\n",
    "    for occur_time in read_data[\"timestamp\"]:\n",
    "        occur_time = eval(occur_time)\n",
    "        if occur_time>=beginS and occur_time<beginS+deltaSecond:#这里是deltaSecond = 1s  是应该加1  而不是1000\n",
    "            cnt+=1\n",
    "    for occur_time in syn_read_data[\"timestamp\"]:\n",
    "        occur_time = eval(occur_time)\n",
    "        if occur_time>=beginS and occur_time<beginS+deltaSecond:#这里是1s  是应该加1  而不是1000\n",
    "            cnt+=1\n",
    "    for occur_time in ahead_read_data[\"timestamp\"]:\n",
    "        occur_time = eval(occur_time)\n",
    "        if occur_time>=beginS and occur_time<beginS+deltaSecond:#这里是1s  是应该加1  而不是1000\n",
    "            cnt+=1\n",
    "    return cnt\n",
    "                \n",
    "def cnt_w_1s(beginS,deltaSecond=1):\n",
    "#     beginS = eval(beginS) \n",
    "    write_data = data[data[\"operation_type\"]==\"W\"]  \n",
    "    cnt = 0\n",
    "    for occur_time in write_data[\"timestamp\"]:\n",
    "        occur_time = eval(occur_time)\n",
    "        if occur_time>=beginS and occur_time<beginS+deltaSecond:#这里是1s  是应该加1  而不是1000\n",
    "            cnt+=1\n",
    "    return cnt\n",
    "\n",
    "def getMaxTime(timestamp_lst):\n",
    "    #传入的是整个数据的timestamp列\n",
    "    return eval(max(timestamp_lst)) #返回ms值\n",
    "\n",
    "#随时间的变化图  要求per second  所以是1s\n",
    "def generate_time_Xaxis(deltaSecond=1): #interval:区间的个数\n",
    "    endS = math.ceil(getMaxTime(data[\"timestamp\"])) #endSecond (已向上取整)\n",
    "    X_axis = [i for i in range(endS+1)]\n",
    "    #print(\"X_axis\",X_axis)\n",
    "    return X_axis\n",
    "def generate_y_axis(x_axis):\n",
    "    y_axis = []\n",
    "    global read_cnt\n",
    "    global write_cnt\n",
    "    read_cnt = []  #每秒的read请求个数\n",
    "    write_cnt = [] #每秒的write请求个数\n",
    "    from tqdm import tqdm\n",
    "    for i in tqdm(range(len(x_axis))):\n",
    "        read_cnt.append(cnt_r_1s(x_axis[i]))\n",
    "        write_cnt.append(cnt_w_1s(x_axis[i]))\n",
    "\n",
    "    \n",
    "\n",
    "x_axis = generate_time_Xaxis(10) #本负载均可使用此x轴(per second)\n",
    "generate_y_axis(x_axis) #根据x对应的时间生成\n",
    "\n",
    "plt.plot(x_axis, read_cnt, marker='o', markersize=3)  # 绘制折线图，添加数据点，设置点的大小\n",
    "plt.plot(x_axis, write_cnt, marker='o', markersize=3)\n",
    "plt.legend(['read_amount', 'write_amount'])  # 设置折线名称\n",
    "plt.title(\"numbers of read and write request per second\")\n",
    "plt.xlabel(\"time_stamp\")\n",
    "plt.ylabel(\"request_amount\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9e9dda7",
   "metadata": {},
   "outputs": [],
   "source": [
    "r = sum(read_cnt)\n",
    "w = sum(write_cnt)\n",
    "print(\"读请求数:\",r)\n",
    "print(\"写请求数:\",w)\n",
    "if sum(write_cnt)!=0:\n",
    "    read_write_ratio = r/w\n",
    "else:\n",
    "    read_write_ratio = \"no write request\"\n",
    "print(\"读写请求比例为:\",read_write_ratio)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4e17e63b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "平均IOPS： 193358.328681604\n"
     ]
    }
   ],
   "source": [
    "# 任务 3 ：计算平均IOPS\n",
    "AVG_IOPS = load0_request_num / getMaxTime(data[\"timestamp\"]) \n",
    "print(\"平均IOPS：\",AVG_IOPS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a61c830a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y轴请求数目数组: [37963, 3091, 2343, 698, 705, 756, 15496, 57316, 9720, 310, 292, 315, 35901, 42546, 4069, 756, 1636, 601, 32562, 35741, 3915, 901, 1095, 47890, 4668, 1625, 1471, 6112, 79232, 4642, 897, 1833, 26009, 45540, 888, 5224, 42375, 23514, 2362, 2373, 2949, 2128, 24182, 4939, 2032, 22954, 25345, 3382, 93064, 9547, 56421, 11695, 28222, 24524, 24865, 35421, 30399, 1833, 2977, 1504, 653, 12862, 6404, 10698, 11434, 32428, 7146, 963, 403, 718, 623, 2900, 62457, 35043, 16404, 568, 319, 289, 405, 14789, 6455, 1676, 882, 571, 16106, 6531, 2100, 2794, 5433, 4330, 3485, 16904, 35909, 4530, 912, 1444, 4848, 8209, 21572, 12961, 6981]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'request_amount')"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 任务4：负载的IOPS随时间变化示意图？（画图显示结果，参考示列3）？\n",
    "\n",
    "# per second \n",
    "def cnt_request_per_delta(beginS,deltaSecond=1): \n",
    "    cnt = 0\n",
    "    for occur_time in data[\"timestamp\"]:\n",
    "        occur_time = eval(occur_time)\n",
    "        if occur_time>=beginS and occur_time<beginS+deltaSecond:#这里是1s  是应该加1  而不是1000\n",
    "            cnt+=1\n",
    "    return cnt\n",
    "\n",
    "y_axis_request_cnt = []\n",
    "for i in tqdm(range(len(x_axis))): \n",
    "    y_axis_request_cnt.append(cnt_request_per_delta(x_axis[i]))\n",
    "print(\"y轴请求数目数组:\",y_axis_request_cnt)\n",
    "\n",
    "plt.plot(x_axis, y_axis_request_cnt, marker='o', markersize=3)  # 绘制折线图，添加数据点，设置点的大小\n",
    "plt.title(\"numbers of I/O request per second\")\n",
    "plt.xlabel(\"time_stamp\")\n",
    "plt.ylabel(\"request_amount\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "878667d0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x_axis_per_hour: [0, 1]\n",
      "y_axis_request_cnt_per_hour: [19335542] hour: 0\n",
      "y_axis_request_cnt_per_hour: [19335542, 0] hour: 1\n",
      "y轴请求数目数组: [19335542, 0]\n"
     ]
    }
   ],
   "source": [
    "# per hour\n",
    "def generate_time_Xaxis_per_hour(deltaHour=1): #interval:区间的个数\n",
    "    endS = math.ceil(getMaxTime(data[\"timestamp\"])/3600) #endSecond (已向上取整)\n",
    "    X_axis = [i for i in range(endS+1)]\n",
    "    #print(\"X_axis\",X_axis)\n",
    "    return X_axis\n",
    "x_axis_per_hour = generate_time_Xaxis_per_hour() \n",
    "print(\"x_axis_per_hour:\",x_axis_per_hour)\n",
    "\n",
    "y_axis_request_cnt_per_hour = []\n",
    "for i in tqdm(range(len(x_axis_per_hour))): \n",
    "    y_axis_request_cnt_per_hour.append(cnt_request_per_delta(x_axis_per_hour[i]*3600,3600)) #求出各个小时内请求的数量\n",
    "    print(\"y_axis_request_cnt_per_hour:\",y_axis_request_cnt_per_hour,\"hour:\",x_axis_per_hour[i])\n",
    "print(\"y轴请求数目数组:\",y_axis_request_cnt_per_hour)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "eaf67510",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "         8  0    128      256    208    152    104       24    224     40  \\\n",
      "0  1548669  1  45421  1018750  41441  29667  37774  1751583  37462  94886   \n",
      "\n",
      "   ...  1088  1264  792  1936  1928  2008  760  1312  816  1120  \n",
      "0  ...    12     4    8     4     4     4    4     4   12     4  \n",
      "\n",
      "[1 rows x 244 columns]\n",
      "平均请求大小为: 79.57888659133528\n"
     ]
    }
   ],
   "source": [
    "y_axis_IOsize_frequency = {}\n",
    "for item in tqdm(data[\"IO_size\"]):\n",
    "    if y_axis_IOsize_frequency.get(item)==None:\n",
    "        temp = {str(item):[1]} #全部转为字符串  使用list是为了便于转为datafrmae\n",
    "        y_axis_IOsize_frequency.update(temp)\n",
    "    else:\n",
    "        (y_axis_IOsize_frequency[str(item)])[0]+=1\n",
    "        \n",
    "# print(y_axis_IOsize_frequency.keys())\n",
    "\n",
    "IO_SIZE_TABLE = {\n",
    "    \"请求大小\":list(y_axis_IOsize_frequency.keys()),\n",
    "    \"出现次数\":list(y_axis_IOsize_frequency.values())\n",
    "}\n",
    "IO_SIZE_TABLE = pd.DataFrame(y_axis_IOsize_frequency)\n",
    "print(IO_SIZE_TABLE)\n",
    "\n",
    "\n",
    "#load0_request_num #总的请求数目\n",
    "IO_SIZE_SUM = 0\n",
    "for key,value in y_axis_IOsize_frequency.items():\n",
    "    IO_SIZE_SUM+=eval(key)*value[0]\n",
    "AVG_IO_SIZE = IO_SIZE_SUM / load0_request_num\n",
    "print(\"平均请求大小为:\",AVG_IO_SIZE)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3625f91",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6bef0e7d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
